package com.etime.shycourse.controller.wxcoupon;

import com.alibaba.fastjson.JSONObject;
import com.etime.shy.common.BaseMessage;
import com.etime.shy.common.ListMessage;
import com.etime.shy.common.PojoMessage;
import com.etime.shycourse.config.Tools;
import com.etime.shycourse.dto.ActivityAndCouponlist;
import com.etime.shycourse.dto.CurrentUser;
import com.etime.shycourse.orde.utils.IdWorker;
import com.etime.shycourse.pojo.ActiveLog;
import com.etime.shycourse.pojo.Couponactivity;
import com.etime.shycourse.services.wxcoupon.interfaces.WXActivityService;
import com.etime.shycourse.services.wxcoupon.interfaces.WXCouponService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信小程序端，与优惠券活动相关的controller
 */
@Api(tags = "微信-优惠券-与优惠券活动相关的controller")
@RestController
@RequestMapping("/wx/activity")
public class WXActivityController {
    @Autowired
    private WXActivityService wxActivityService;
    @Autowired
    private WXCouponService wxCouponService;
    @Autowired
    private Tools tools;

    /**
     * 销售人员获取通过链接分享的活动列表。
     * 这些活动销售人员可以通过分享链接的方式进行分享。
     *
     * @return
     */
    @ApiOperation("销售人员获取通过链接分享的活动列表")
    @GetMapping("/saler/list")
    public ListMessage<Couponactivity> getShareActivityList() {
        ListMessage<Couponactivity> msg = new ListMessage<>();
        List<Couponactivity> list = wxActivityService.getShareActivityList();
        if (list != null && list.size() > 0) {
            msg.setCode(1);
            msg.setDatalist(list);
        } else {
            msg.setCode(0);
            msg.setMsg("没有正在进行的可分享的优惠券活动");
        }
        return msg;
    }

    /**
     * 根据活动id，获取活动的详细信息，包含活动所包含的优惠券信息
     *
     * @param activityid 活动id
     * @return
     */
    @ApiOperation("根据活动id获取活动详细信息的数据接口。包含活动的优惠券列表")
    @ApiImplicitParam(name = "activityid", value = "活动id")
    @GetMapping("/getbyid/{activityid}")
    public PojoMessage<ActivityAndCouponlist> getActivityById(@PathVariable("activityid") Integer activityid) {
        PojoMessage<ActivityAndCouponlist> msg = new PojoMessage<>();
        //根据id查询活动详情
        ActivityAndCouponlist activityAndCouponlist = wxActivityService.getActivityAndCouponListById(activityid);
        msg.setCode(1);
        msg.setData(activityAndCouponlist);
        return msg;
    }

    /**
     * 根据活动id获取活动的分享参数。
     * 逻辑算法说明：
     * 1 分享人的id（从currentUser中获取）；
     * 2 活动id
     * 3 判断活动是否允许转发。--pwd参数
     * 3.1 如果允许转发，不需要pwd参数
     * 3.2 如果不允许转发，则需要pwd参数--使用雪花算法生成一个不重复的密码。
     * 并需要在活动记录中记录分享。
     * 4 参数格式：p=xxx&r=xxx
     * 4.1 p的内容为：{"activityid":"xxx","pwd":"xxx","userid":"xxx"}
     * 先进行base64加密；然后进行url编码。
     * 4.2 r的内容为：当前日期的数字表示-时间戳
     *
     * @param activityid
     * @return
     */
    @ApiOperation("根据活动id获取活动的分享参数，用于市场人员去分享活动")
    @ApiImplicitParam(name = "activityid", value = "活动id")
    @GetMapping("/getshareparam/{activityid}")
    public BaseMessage getShareActivityParam(@PathVariable("activityid") Integer activityid, HttpServletRequest request) {
        BaseMessage msg = new BaseMessage();
        //1 获取分享人的id（从currentUser中获取）
        String token = request.getHeader("token");
        //String token = "1679091c5a880faf6fb5e6087eb1b2dc";
        CurrentUser currentUser = tools.getCurrentUserFromRedis(token);
        if (currentUser == null) {
            msg.setCode(-2);
            msg.setMsg("未获取到用户信息；可能登录超时或者非法访问。");
        } else {
            if (currentUser.getUser() != null) {
                Map<String, Object> map = new HashMap<>();
                //判断活动是否允许转发
                Couponactivity couponactivity = wxActivityService.getActivityById(activityid);
                boolean flag = true;
                //不允许转发-生成密码，并记录到活动参与记录中
                if (couponactivity.getActiveallowdforward() == 2) {
                    ActiveLog activeLog = new ActiveLog();
                    activeLog.setCactivityid(activityid);
                    activeLog.setActivefromuserid(currentUser.getUser().getUserid());
                    activeLog.setActivefromusername(currentUser.getUser().getUsertruename() + "(" + currentUser.getUser().getNickname() + ")");
                    activeLog.setActivesharetime(new Date());
                    IdWorker idWorker = new IdWorker();
                    String pwd = idWorker.nextId() + "";
                    activeLog.setActivesharepwd(pwd);
                    activeLog.setActivesharestate(1);
                    int rtn = wxActivityService.insertActiveLog(activeLog);
                    if (rtn > 0) {
                        //保存成功,分享,添加分享密码进入参数
                        map.put("pwd", pwd);
                    } else {
                        //保存失败，不分享
                        msg.setCode(-2);
                        msg.setMsg("分享失败，保存分享记录失败。");
                        flag = false;
                    }
                }
                //处理参数
                if (flag) {
                    map.put("activityid", activityid);
                    map.put("userid", currentUser.getUser().getUserid());
                    try {
                        byte[] bytes = JSONObject.toJSONBytes(map);
                        BASE64Encoder encoder = new BASE64Encoder();
                        String str = URLEncoder.encode(encoder.encode(bytes), "utf-8");
                        String param = "p=" + str + "&r=" + System.currentTimeMillis();
                        msg.setCode(1);
                        msg.setMsg(param);
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return msg;
    }

    /**
     * 根据优惠券发放方式（程序中定义好的特定动作）判断是否有可用的优惠券活动。
     * 如果有活动，则将用户可以参与的活动记录到活动参与记录表中。
     *
     * @param activitytypeid 发放方式id
     * @return code=-2 用户没有授权登录；code=0 没有活动；code=1 有活动（msg=活动id）；
     */
    @ApiOperation("判断用户是否有可以参与的优惠券活动。")
    @ApiImplicitParam(name = "activitytypeid", value = "发放方式id：" +
            "1000\t活动链接分享\t通过销售人员分享的活动链接进行活动分享\t1\n" +
            "2000\t新用户注册\t用户第一次授权登录时\t1\n" +
            "3000\t完善个人信息\t在用户完善个人信息的时候触发活动\t1\n" +
            "4000\t支付成功\t在用户购买课程，并支付成功后触发活动\t1\n" +
            "5000\t用户点击按钮\t在小程序中用户通过点击某些特定按钮触发活动\t1\n" +
            "code=-2 用户没有授权登录；code=0 没有活动；code=1 有活动（msg=活动id）")
    @GetMapping("/hasactivity/{activitytypeid}")
    public BaseMessage checkHasActivity(@PathVariable("activitytypeid") Integer activitytypeid, HttpServletRequest request) {
        BaseMessage msg = new BaseMessage();
        //判断用户是否登录
        String token = request.getHeader("token");
        //String token = "1679091c5a880faf6fb5e6087eb1b2dc";
        CurrentUser currentUser = tools.getCurrentUserFromRedis(token);
        if (currentUser == null) {
            msg.setCode(-2);
            msg.setMsg("未获取到用户信息；可能登录超时或者非法访问。");
        } else {
            //查询出所有可用的活动列表
            List<Couponactivity> activelist = wxActivityService.getUsedActivityListByTypeId(activitytypeid);
            if (activelist != null && activelist.size() > 0) {
                //有活动,添加活动参与记录
                Integer activeid = null;
                for (Couponactivity active : activelist) {
                    //判断活动是否可以重复参加，如果允许则直接记录参与记录；
                    //如果不允许，则判断用户是否已经参与了活动，如果没有则记录参与记录，如果有，则忽略活动
                    if (active.getActiveallowedre() == 2) {
                        //不允许，判断是否参与了活动
                        List<ActiveLog> loglist = wxActivityService.selectActiveLogByUserIdAdnActiveId(currentUser.getUser().getUserid(), active.getCactivityid());
                        if (loglist != null && loglist.size() > 0) {
                            continue;
                        }
                    }
                    ActiveLog log = new ActiveLog();
                    log.setCactivityid(active.getCactivityid());
                    log.setActivesharestate(1);
                    log.setActivetouserid(currentUser.getUser().getUserid());
                    log.setActivetousername(currentUser.getUser().getUsertruename() + "(" + currentUser.getUser().getNickname() + ")");
                    int savlogrtn = wxActivityService.insertActiveLog(log);
                    if (savlogrtn > 0) {
                        activeid = active.getCactivityid();
                    }
                }
                if (activeid != null) {
                    //有活动参与
                    msg.setCode(1);
                    msg.setMsg(activeid.toString());
                } else {
                    //无活动
                    msg.setCode(0);
                    msg.setMsg("没有可用优惠活动");
                }
            } else {
                //无活动
                msg.setCode(0);
                msg.setMsg("没有可用优惠活动");
            }
        }
        return msg;
    }

    /**
     * 查询用户所有可以参与的活动列表（活动有效，且未过期）
     *
     * @return code=-2:未登录；code=0 没有未领取的优惠券；code=1 有未领取的优惠券
     */
    @ApiOperation("查询用户所有可以参与的活动列表\r\n" +
            "返回值：code=-2:未登录；\r\ncode=0 没有未领取的优惠券；\r\n" +
            "code=1 有未领取的优惠券,dataList中存放活动列表")
    @GetMapping("/myactivity")
    public ListMessage<Couponactivity> selectUsedActiveByUserId(HttpServletRequest request) {
        ListMessage<Couponactivity> msg = new ListMessage<>();
        String token = request.getHeader("token");
        //String token = "1679091c5a880faf6fb5e6087eb1b2dc";
        CurrentUser currentUser = tools.getCurrentUserFromRedis(token);
        if (currentUser == null) {
            msg.setCode(-2);
            msg.setMsg("未获取到用户信息；可能登录超时或者非法访问。");
        } else {
            List<Couponactivity> activelist = wxActivityService.getActivityListByUserId(currentUser.getUser().getUserid());
            if (activelist != null && activelist.size() > 0) {
                msg.setCode(1);
                msg.setDatalist(activelist);
            } else {
                msg.setCode(0);
                msg.setMsg("没有优惠券可领取");
            }
        }
        return msg;
    }


    /**
     * 用户参与活动页面中，查询活动详情的数据接口。数据包含活动详情和活动中所包含的可用优惠券列表
     * 逻辑描述：
     * 1、判断用户是否登录，如果没有登录，则返回code=-2
     * 2、判断参数：p和activeid。
     * 2.1 如果p存在，则对p进行解码，然后获取到活动id。
     * 如果p解码结果中包含pwd字段，则表示此活动只能只能参与一次，那么判断活动参与记录中对应活动
     * 和pwd的记录状态，是否为：未领取状态。如果已经领取，则返回code=-3 msg=该活动链接已使用。
     * 2.2 如果activeid存在，则直接使用此活动id
     * 3 查询出优惠券列表后，判断优惠券是否允许重复领取。
     * 如果不允许重复领取，则需要判断用户是否已经领取过该优惠券。
     * 如果领取过，则需要标记此优惠券已经领取过
     *
     * @param p        分享参数。如果是通过分享链接进入的，则会携带此参数
     * @param r        分享参数中的随机码。
     * @param activeid 如果是通过特定链接进入的活动页面，则直接携带活动id
     * @param request
     * @return code:-2 未登录；-4 参数错误； -3 已领取
     */
    @ApiOperation("用户进入到活动详情页面--查询活动详情；包含活动的优惠券以及优惠券是否已经领取信息.\r\n" +
            "在优惠券中，使用备用字段：couponfiled1=1；表示用户已经领取了此优惠券，不能再次领取。")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "p", value = "分享参数，有activeid可以不传"),
            @ApiImplicitParam(name = "r", value = "分享参数，随机码，有activeid可以不传"),
            @ApiImplicitParam(name = "activeid", value = "活动id，有p参数的时候可以不用传递。")
    })
    @GetMapping("/getdetail/foruser")
    public PojoMessage<ActivityAndCouponlist> selectActiveByIdForUser(String p, String r, Integer activeid, HttpServletRequest request) {
        PojoMessage<ActivityAndCouponlist> msg = new PojoMessage<>();
        if ((p == null || p.equals("")) && activeid == null) {
            msg.setCode(-4);
            msg.setMsg("参数错误");
            return msg;
        }
        String token = request.getHeader("token");
        //String token = "1679091c5a880faf6fb5e6087eb1b2dc";
        CurrentUser currentUser = tools.getCurrentUserFromRedis(token);
        if (currentUser == null) {
            msg.setCode(-2);
            msg.setMsg("未获取到用户信息；可能登录超时或者非法访问。");
            return msg;
        }
        if (p != null && !p.equals("")) {
            //使用p参数,对p进行解码
            Map<String, Object> pmap = decodeparam(p);
            if (pmap != null) {
                //activeid = Integer.parseInt(pmap.get("activityid")+"");
                String s = pmap.get("activityid").toString();
                activeid = Integer.parseInt(s);
                //判断是否有pwd参数
                boolean haspwd = pmap.containsKey("pwd");
                if (haspwd) {
                    //判断该链接是否有效
                    ActiveLog flag = wxActivityService.checkActiveUrlUsed(activeid, pmap.get("pwd").toString());
                    if (flag == null) {
                        //无效
                        msg.setCode(-3);
                        msg.setMsg("该活动链接无效，或者已被领取");
                        return msg;
                    }
                }
            } else {
                msg.setCode(-4);
                msg.setMsg("参数错误");
                return msg;
            }
        }
        //使用activeid进行处理
        ActivityAndCouponlist activityAndCouponlist = wxActivityService.getActivityAndCouponListByIdAndUserid(activeid, currentUser.getUser().getUserid());
        msg.setCode(1);
        msg.setData(activityAndCouponlist);
        return msg;
    }

    /**
     * 对分享参数进行解析
     *
     * @param param
     * @return
     */
    private Map<String, Object> decodeparam(String param) {
        try {
            String urldecodestr = URLDecoder.decode(param, "utf-8");
            //进行base64解码
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes = decoder.decodeBuffer(urldecodestr);
            Map<String, Object> map = (Map<String, Object>) JSONObject.parse(bytes);
            return map;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 领取优惠券数据接口
     * 逻辑描述：
     * 1、记录活动参与记录
     * 1.1 判断是否有参数p，如果有，则还需要判断是否有pwd属性，如果有则进行修改活动参与记录；
     * 1.2 如果没有p参数，或者没有pwd属性，则直接进行增加活动记录。
     * 2、记录每一张优惠券的领取记录（如果couponfiled1=1，则不记录，不领取）
     * 3、记录每一张优惠券的使用日志（记录领取日志。）
     * //     * @param activityAndCouponlist 加载活动详细信息时，从后端接收到的数据。重新传入到后台数据接口。
     * //     * @param p 分享参数
     *
     * @return
     */
    @ApiOperation("用户在活动详情页面中领取优惠券接口。一键领取")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "activityAndCouponlist", value = "活动详情及优惠券列表，将获取的信息直接回传"),
            @ApiImplicitParam(name = "p", value = "如果是分享的活动，则将分享链接中的p参数传递回来")
    })
    @PostMapping("/coupon/draw")
    public Map<String, String> drawCoupon(@RequestBody PojoMessage<ActivityAndCouponlist> params, HttpServletRequest request) {
        //@RequestBody ActivityAndCouponlist activityAndCouponlist,String p
        ActivityAndCouponlist activityAndCouponlist = params.getData();
        String p = params.getMsg();
        Map<String, String> rtnmap = new HashMap<>();
        String token = request.getHeader("token");
        //String token = "1679091c5a880faf6fb5e6087eb1b2dc";
        CurrentUser currentUser = tools.getCurrentUserFromRedis(token);
        if (currentUser == null) {
            rtnmap.put("code", "-2");
            rtnmap.put("msg", "未获取到用户信息；可能登录超时或者非法访问。");
            return rtnmap;
        }
        //判断p是否存在，存在则需要获取pwd参数
        String pwd = null;
        if (p != null && !p.equals("")) {
            Map<String, Object> map = decodeparam(p);
            if (map.containsKey("pwd")) {
                pwd = map.get("pwd").toString();
            }
        }
        rtnmap = wxActivityService.drawCoupon(activityAndCouponlist,
                currentUser.getUser().getUserid(),
                currentUser.getUser().getUsertruename() + "(" + currentUser.getUser().getNickname() + ")",
                pwd);
        return rtnmap;
    }


    /**
     * 参与活动后，查询是否还有其他活动可以参与。如果有则返回一个活动id给用户
     *
     * @param request
     * @return
     */
    @ApiOperation("参与活动后，查询是否还有其他活动可以参与。如果有则返回一个活动id给用户")
    @GetMapping("/nextactive")
    public BaseMessage selectNextActiveByUserId(HttpServletRequest request) {
        BaseMessage msg = new BaseMessage();
        msg.setCode(0);
        String token = request.getHeader("token");
        //String token = "1679091c5a880faf6fb5e6087eb1b2dc";
        CurrentUser currentUser = tools.getCurrentUserFromRedis(token);
        if (currentUser == null) {
            msg.setCode(-2);
            msg.setMsg("未获取到用户信息；可能登录超时或者非法访问。");
            return msg;
        } else {
            List<Couponactivity> list = wxActivityService.getActivityListByUserId(currentUser.getUser().getUserid());
            if (list != null && list.size() > 0) {
                msg.setCode(1);
                msg.setMsg(list.get(0).getCactivityid() + "");
            }
        }
        return msg;
    }

}
